package com.ts.jdbc;

import com.ts.comm.SysString;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.rowset.SqlRowSet;

import javax.naming.Context;
import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by yingzi on 2017-3-23.
 */
public class SysDB {

    private static DynamicDataSource dynamicDataSource = new DynamicDataSource();

    /**
     * 获得XML配置的数据源连接对
     *
     * @return
     */
    public static Connection getConn() throws SQLException {
        return dynamicDataSource.getConnection();
    }

    /**
     * 获得第三方连接
     *
     * @param sIP           IP地址
     * @param iPost         端口号
     * @param sUser         用户名
     * @param sPwd          密码
     * @param sDataBaseName 数据库SID或ServiceName
     * @return
     * @throws Exception
     */
    public static Connection getDBConn(String sIP, int iPost, String sUser, String sPwd, String sDataBaseName)
            throws Exception {
        Connection con = null;
        String sConnStr = "";
        String sDriverName = "";
        sConnStr = "jdbc:oracle:thin:@" + sIP + ":" + iPost + "/" + sDataBaseName;
        sDriverName = "oracle.jdbc.driver.OracleDriver";
        Class.forName(sDriverName);
        con = DriverManager.getConnection(sConnStr, sUser, sPwd);
        return con;
    }

    /**
     * 获得第三方连接
     *
     * @param sJndiName 连接池名称
     *                  tomcat 写法 java:comp/env/名称
     * @return
     * @throws Exception
     */
    public static Connection getConn(String sJndiName) throws Exception {
        Connection con = null;
        javax.sql.DataSource ds = null;
        Context ctx = null;
        try {
            if (SysString.isEmpty(sJndiName)) {
                con = getConn();
            } else {
                Object o = ctx.lookup(sJndiName);
                javax.sql.DataSource dsTax = (javax.sql.DataSource) o;
                con = dsTax.getConnection();
                if (con == null) {
                    throw new Exception("无法连接数据库！");
                }
            }
        } catch (Exception e) {
            throw e;
        }
        return con;
    }

    /**
     * 方法说明：各种数据库操作关闭
     *
     * @param args
     * @throw
     */
    public static void closeConn(Object... args) {
        Object obj = null;
        Connection con = null;
        try {
            if (args != null) {
                for (int i = 0; i < args.length; i++) {
                    obj = args[i];
                    if (obj != null) {
                        if (obj instanceof ResultSet) {
                            ((ResultSet) obj).close();
                        } else if (obj instanceof PreparedStatement) {
                            ((PreparedStatement) obj).close();
                        } else if (obj instanceof Statement) {
                            ((Statement) obj).close();
                        } else if (obj instanceof Connection) {
                            con = ((Connection) obj);
                            try {
                                if (con.getAutoCommit() == false) {
                                    con.rollback();
                                    con.setAutoCommit(true);
                                }
                            } catch (Exception e) {
                            }
                            con.close();
                        }
                    }
                }
            }
        } catch (Exception e) {
        }
    }

    /**
     * 获得sql语句int值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @param params 参数
     * @return int
     * @throws Exception
     */
    public static int getIntValue(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String,Object> params)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,params,Integer.class);
    }

    /**
     * 获得sql语句int值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @param params 参数
     * @return int
     * @throws Exception
     */
    public static int getIntValue(JdbcTemplate jdbcTemplate, String sql, Object...params)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,Integer.class,params);
    }

    /**
     * 获得sql语句int值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @return int
     * @throws Exception
     */
    public static int getIntValue(NamedParameterJdbcTemplate jdbcTemplate, String sql)
            throws Exception{
        Map<String,Object> param=new HashMap<String,Object>();
        return jdbcTemplate.queryForObject(sql,param,Integer.class);
    }
    /**
     * 获得sql语句int值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @return int
     * @throws Exception
     */
    public static int getIntValue(JdbcTemplate jdbcTemplate, String sql)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,Integer.class);
    }

    /**
     * 获得sql语句String值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @param params 参数
     * @return String
     * @throws Exception
     */
    public static String getStringValue(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String,Object> params)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,params,String.class);
    }
    /**
     * 获得sql语句String值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @param params 参数
     * @return String
     * @throws Exception
     */
    public static String getStringValue(JdbcTemplate jdbcTemplate, String sql,  Object... params)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,String.class,params);
    }
    /**
     * 获得sql语句String值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @return String
     * @throws Exception
     */
    public static String getStringValue(NamedParameterJdbcTemplate jdbcTemplate, String sql)
            throws Exception{
        Map<String,Object> param=new HashMap<String,Object>();
        return jdbcTemplate.queryForObject(sql,param,String.class);
    }
    /**
     * 获得sql语句String值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @return String
     * @throws Exception
     */
    public static String getStringValue(JdbcTemplate jdbcTemplate, String sql)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,String.class);
    }

    /**
     * 获得sql语句Double值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @param params 参数
     * @return Double
     * @throws Exception
     */
    public static double getDoubleValue(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String,Object> params)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,params,Double.class);
    }

    /**
     * 获得sql语句Double值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @param params 参数
     * @return Double
     * @throws Exception
     */
    public static double getDoubleValue(JdbcTemplate jdbcTemplate, String sql,  Object... params)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,Double.class,params);
    }
    /**
     * 获得sql语句Double值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @return Double
     * @throws Exception
     */
    public static double getDoubleValue(NamedParameterJdbcTemplate jdbcTemplate, String sql)
            throws Exception{
        Map<String,Object> param=new HashMap<String,Object>();
        return jdbcTemplate.queryForObject(sql,param,Double.class);
    }
    /**
     * 获得sql语句Double值
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @return Double
     * @throws Exception
     */
    public static double getDoubleValue(JdbcTemplate jdbcTemplate, String sql)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,Double.class);
    }

    /**
     * 获得SQL语句map存储
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @param params 参数
     * @return
     * @throws Exception
     */
    public static Map<String,Object> getMapValue(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String, Object> params)
            throws Exception{
        return jdbcTemplate.queryForMap(sql,params);
    }
    /**
     * 获得SQL语句map存储
     * @param jdbcTemplate jdbc模板
     * @param sql
     * @param params 参数
     * @return
     * @throws Exception
     */
    public static Map<String,Object> getMapValue(JdbcTemplate jdbcTemplate, String sql, Object...params)
            throws Exception{
        return jdbcTemplate.queryForMap(sql,params);
    }
    /**
     * 根据SQL语句获取Java bean对象（对象属性必须和数据库字段名一致）
     * @param jdbcTemplate
     * @param sql
     * @param params 参数
     * @param cls
     * @return Class
     * @throws Exception
     */
    public static <E> Class<E> getClassValue(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String,Object> params,Class<E> cls)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,params,new BeanPropertyRowMapper<Class<E>>((Class<Class<E>>) cls));
    }
    /**
     * 根据SQL语句获取Java bean对象（对象属性必须和数据库字段名一致）
     * @param jdbcTemplate
     * @param sql
     * @param params 参数
     * @param cls
     * @return Class
     * @throws Exception
     */
    public static <E> Class<E> getClassValue(JdbcTemplate jdbcTemplate, String sql,Class<E> cls,Object... params)
            throws Exception{
        return jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<Class<E>>((Class<Class<E>>) cls),params);
    }
    /**
     *获得结果集
     * @param jdbcTemplate
     * @param sql
     * @return List<HashMap<String,Object>>
     */
    public static List<Map<String,Object>> getRows(NamedParameterJdbcTemplate jdbcTemplate, String sql)
            throws Exception
    {
        Map<String,Object> params=new HashMap<String,Object>();
        return jdbcTemplate.queryForList(sql,params);
    }
    /**
     *获得结果集
     * @param jdbcTemplate
     * @param sql
     * @param params 参数
     * @return List<HashMap<String,Object>>
     */
    public static List<Map<String,Object>> getRows(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String,Object> params)
    throws Exception
    {
        if(params==null){
            params=new HashMap<String,Object>();
        }
        return jdbcTemplate.queryForList(sql,params);
    }
    /**
     *获得结果集
     * @param jdbcTemplate
     * @param sql
     * @param iPageIndex 当前第几页（从0开始）
     * @param iPageSize  每页多少条记录
     * @param params 参数
     * @return List<HashMap<String,Object>>
     */
    public static List<Map<String,Object>> getRows(NamedParameterJdbcTemplate jdbcTemplate, String sql,int iPageIndex,int iPageSize, HashMap<String,Object> params)
            throws Exception
    {
        int iBegPos = ((iPageIndex-1) * iPageSize) + 1;
        int iEndPos =  iPageIndex * iPageSize;
        StringBuilder sb=new StringBuilder();
        sb.append( " with z as ( " + sql + ")");
        sb.append( " select * from (");
        sb.append( "        Select rownum FROWNUM,z.* from z");
        sb.append( "    where rownum <= " + iEndPos);
        sb.append( " ) where FROWNUM >= " + iBegPos);

        return jdbcTemplate.queryForList(sb.toString(),params);
    }
    /**
     *获得结果集
     * @param jdbcTemplate
     * @param sql
     * @param args 参数
     * @return List<HashMap<String,Object>>
     */
    public static List<Map<String,Object>> getRows(JdbcTemplate jdbcTemplate, String sql, Object...args)
            throws Exception
    {
        return jdbcTemplate.queryForList(sql,args);
    }
    /**
     *获得结果集
     * @param jdbcTemplate
     * @param sql
     * @param iPageIndex 当前第几页（从0开始）
     * @param iPageSize  每页多少条记录
     * @param args 参数
     * @return List<HashMap<String,Object>>
     */
    public static List<Map<String,Object>> getRows(JdbcTemplate jdbcTemplate, String sql,int iPageIndex,int iPageSize, Object...args)
            throws Exception
    {
		int iBegPos = ((iPageIndex-1) * iPageSize) + 1;
		int iEndPos =  iPageIndex * iPageSize;
        StringBuilder sb=new StringBuilder();
        sb.append( " with z as ( " + sql + ")");
        sb.append( " select * from (");
        sb.append( "        Select rownum FROWNUM,z.* from z");
        sb.append( "    where rownum <= " + iEndPos);
        sb.append( " ) where FROWNUM >= " + iBegPos);

        return jdbcTemplate.queryForList(sb.toString(),args);
    }
    /**
     *获得结果集
     * @param jdbcTemplate
     * @param sql
     * @return List<HashMap<String,Object>>
     */
    public static List<Map<String,Object>> getRows(JdbcTemplate jdbcTemplate, String sql)
            throws Exception
    {
        return jdbcTemplate.queryForList(sql);
    }
    /**
     *获得结果集,只支持基本类型
     * @param jdbcTemplate
     * @param sql
     * @param params 参数
     * @return List<?>
     */
    public static <E>  List<E> getRows(NamedParameterJdbcTemplate jdbcTemplate, String sql
            , Object[] params,Class<E> cls)
            throws Exception
    {
        return jdbcTemplate.getJdbcOperations().query(sql, params,new BeanPropertyRowMapper<E>(cls));
    }
    /**
     *获得结果集,只支持基本类型
     * @param jdbcTemplate
     * @param sql
     * @param params 参数
     * @return List<?>
     */
    public static <E>  List<E> getRows(JdbcTemplate jdbcTemplate, String sql
            , Object[] params,Class<E> cls)
            throws Exception
    {
        return jdbcTemplate.query(sql, params,new BeanPropertyRowMapper<E>(cls));
    }
    /**
     * 获得int类型集合
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */

    public static List<Integer> getIntList(NamedParameterJdbcTemplate jdbcTemplate, String sql
            , HashMap<String,Object> params)
            throws Exception
    {
        return jdbcTemplate.queryForList(sql,params,Integer.class);
    }
    /**
     * 获得int类型集合
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */

    public static List<Integer> getIntList(JdbcTemplate jdbcTemplate, String sql, Object... params)
            throws Exception
    {
        return jdbcTemplate.queryForList(sql,Integer.class,params);
    }
    /**
     * 获得int类型集合
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */

    public static List<Integer> getIntList(NamedParameterJdbcTemplate jdbcTemplate, String sql
            , MapSqlParameterSource params)
            throws Exception
    {
        return jdbcTemplate.queryForList(sql,params,Integer.class);
    }
    /**
     * 获得String类型集合
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */

    public static List<String> getStrList(NamedParameterJdbcTemplate jdbcTemplate, String sql
            , HashMap<String,Object> params)
            throws Exception
    {
        return jdbcTemplate.queryForList(sql,params,String.class);
    }
    /**
     * 获得String类型集合
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */

    public static List<String> getStrList(JdbcTemplate jdbcTemplate, String sql
            ,Object... params)
            throws Exception
    {
        return jdbcTemplate.queryForList(sql,String.class,params);
    }
    /**
     * 获得String类型集合
     * @param jdbcTemplate
     * @param sql
     * @param sqlParam
     * @return
     * @throws Exception
     */
    public static List<String> getStrList(NamedParameterJdbcTemplate jdbcTemplate, String sql
            , MapSqlParameterSource sqlParam)
            throws Exception
    {
        return jdbcTemplate.queryForList(sql,sqlParam,String.class);
    }

    /**
     * 获得结果集类 RowSet
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */
    public static SqlRowSet getResultSet(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String,Object> params)
            throws Exception
    {
        return jdbcTemplate.queryForRowSet(sql,params);
    }
    /**
     * 获得结果集类 RowSet
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */
    public static SqlRowSet getResultSet(JdbcTemplate jdbcTemplate, String sql, Object... params)
            throws Exception
    {
        return jdbcTemplate.queryForRowSet(sql,params);
    }

    /**
     * DML 更新操作(insert、update、delete);
     * @param jdbcTemplate
     * @param sql
     * @param params 参数
     * @return int >0更新成功
     * @throws Exception
     */
    public static int update(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String,Object> params)
            throws Exception
    {
        return jdbcTemplate.update(sql,params);
    }
    /**
     * DML 更新操作(insert、update、delete);
     * @param jdbcTemplate
     * @param sql
     * @param params 参数
     * @return int >0更新成功
     * @throws Exception
     */
    public static int update(JdbcTemplate jdbcTemplate, String sql, Object... params)
            throws Exception
    {
        return jdbcTemplate.update(sql,params);
    }
    /**
     * DML 更新操作(insert、update、delete);
     * @param jdbcTemplate
     * @param sql
     * @param params 参数
     * @return int >0更新成功
     * @throws Exception
     */
    public static int update(JdbcTemplate jdbcTemplate, String sql, Object[] params,int[] types)
            throws Exception
    {
        return jdbcTemplate.update(sql,params,types);
    }
    /**
     * DML 更新操作(insert、update、delete);
     * SqlParameterSource ps=new BeanPropertySqlParameterSource(javabean);
     * @param jdbcTemplate
     * @param sql
     * @param sqlSource 参数
     * @return int >0更新成功
     * @throws Exception
     */
    public static int update(NamedParameterJdbcTemplate jdbcTemplate, String sql, SqlParameterSource sqlSource)
            throws Exception
    {
        return jdbcTemplate.update(sql,sqlSource);
    }
    /**
     * DML 更新操作(insert、update、delete);
     * SqlParameterSource ps=new BeanPropertySqlParameterSource(javabean);
     * @param jdbcTemplate
     * @param sql
     * @param sqlSource 参数
     * @return int >0更新成功
     * @throws Exception
     */
    public static int update(JdbcTemplate jdbcTemplate, String sql, SqlParameterSource sqlSource)
            throws Exception
    {
        return jdbcTemplate.update(sql,sqlSource);
    }
    /**
     * DDL 更新操作(create、alter、drop、truncate);
     * @param jdbcTemplate
     * @param sql
     * @return int >0更新成功
     * @throws Exception
     */
    public static void execute(NamedParameterJdbcTemplate jdbcTemplate, String sql)
            throws Exception
    {
         jdbcTemplate.getJdbcOperations().execute(sql);
    }
    /**
     * DDL 更新操作(create、alter、drop、truncate);
     * @param jdbcTemplate
     * @param sql
     * @return int >0更新成功
     * @throws Exception
     */
    public static void execute(JdbcTemplate jdbcTemplate, String sql)
            throws Exception
    {
        jdbcTemplate.execute(sql);
    }

    /**
     * 批量更新操作
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */
    public static int[] batchUpdate(NamedParameterJdbcTemplate jdbcTemplate, String sql, HashMap<String,Object>[] params)
            throws Exception
    {
        return jdbcTemplate.batchUpdate(sql,params);
    }

    /**
     * 批量更新操作
     * @param jdbcTemplate
     * @param sql
     * @param params
	 * @return
     * @throws Exception
     */
    public static int[] batchUpdate(JdbcTemplate jdbcTemplate, String sql,List<Object[]> params)
            throws Exception
    {
        return jdbcTemplate.batchUpdate(sql,params);
    }
    /**
     * 多条sql语句执行更新
     * @param jdbcTemplate
     * @param sql 多条SQL
     * @return
     * @throws Exception
     */
    public static int[] batchUpdate(NamedParameterJdbcTemplate jdbcTemplate, String[] sql)
            throws Exception
    {
        return jdbcTemplate.getJdbcOperations().batchUpdate(sql);
    }
    /**
     * 批量更新操作
     * @param jdbcTemplate
     * @param sql
     * @param params
     * @return
     * @throws Exception
     * List<BeanPropertySqlParameterSource> userSourceList = new ArrayList<BeanPropertySqlParameterSource>();
             for (UserInfo user : users) {
                 userSourceList.add(new BeanPropertySqlParameterSource(user));
             }
             BeanPropertySqlParameterSource[] beanSources  =  userSourceList.toArray(new BeanPropertySqlParameterSource[userSourceList.size()]);
     */
    public static int[] batchUpdate(NamedParameterJdbcTemplate jdbcTemplate, String sql, BeanPropertySqlParameterSource[] params)
            throws Exception
    {
        return jdbcTemplate.batchUpdate(sql,params);
    }

}
